local extension = Package:new("tangz_heg")
extension.extensionName = "new_heg"
extension.game_modes_whitelist = { "mul_heg_mode" }

local H = require "packages/new_heg/util"
local U = require "packages/utility/utility"
-- local D = require "packages/diy_utility/diy_utility"

Fk:loadTranslationTable{
  ["tangz_heg"] = "大唐盛世",
}


local lishimin = General(extension, "hs__n_lishimin", "tangz", 4)
local ceju = fk.CreateTriggerSkill{
  name = "hs__n_ceju",
  anim_type = "drawcard",
  events = {fk.EventPhaseStart},
  can_trigger = function (self, event, target, player, data)
    return target == player and player:hasSkill(self) and player.phase == Player.Play
  end,
  on_use = function (self, event, target, player, data)
    local room = player.room
    local targets = table.filter(room.alive_players, function (p) return H.compareKingdomWith(p, player) end)
    for _, p in ipairs(targets) do
      p:drawCards(1,self.name)
      if p.dead then return end
      if not p:isKongcheng() then
        local card = room:askForCard(p, 1, 1, false, self.name, false, ".", "#hs__n_ceju_showCards")
        H.ShowCards(p, card)
      end
    end
  end
}
local zhenguan_maxCard = fk.CreateMaxCardsSkill{
  name = "#hs__n_ceju_maxCard",
  exclude_from = function (self, player, card)
    local owner = table.find(Fk:currentRoom().alive_players, function (p) return p:hasShownSkill(ceju.name) end)
    if not owner then return end
    if H.compareKingdomWith(player, owner) then
      return card:getMark(MarkEnum.ShownCards) > 0
    end
  end
}
ceju:addRelatedSkill(zhenguan_maxCard)
lishimin:addSkill(ceju)
Fk:loadTranslationTable{
  ["hs__n_lishimin"] = "李世民",
  ["#hs__n_lishimin"] = "兆见寰宇",
  ["designer:hs__n_lishimin"] = "教父",
  ["illustrator:hs__n_lishimin"] = "",

  ["hs__n_ceju"] = "策局",
  [":hs__n_ceju"] = "出牌阶段开始时，你可以令与你势力相同的角色各摸一张牌并明置一张手牌；与你势力相同角色的明置牌不计入手牌上限。",
  ["#hs__n_ceju_showCards"] = "策局：请明置一张手牌。",

  ["~hs__n_lishimin"] = "",
}

local chengzhijie = General(extension, "hs__n_chengzhijie", "tangz", 5)
local piaoyong = fk.CreateTriggerSkill{
  name = "hs__n_piaoyong",
  anim_type = "control",
  events = {fk.CardUsing},
  can_trigger = function (self, event, target, player, data)
    local use_card_times = #player.room.logic:getEventsOfScope(GameEvent.UseCard, 999, function (e)
      local use = e.data[1] 
      return use.from == player.id
    end,Player.HistoryTurn)
    self.cost_data = {times = use_card_times}
    return player:hasSkill(self) and target == player and (use_card_times == 1 or use_card_times == 3) and player.room.current == player
  end,
  frequency = Skill.Compulsory,
  on_use = function (self, event, target, player, data)
    local room = player.room
    if self.cost_data.times == 1 then
      local others = table.map(room:getOtherPlayers(player), Util.IdMapper)
      if #others == 0 then return end
      local tos = room:askForChoosePlayers(player, others, 1, 1, "#hs__n_piaoyong_choose2view", self.name, false)
      local t = room:getPlayerById(tos[1])
      U.viewCards(player, t:getCardIds("h"), self.name)
    else
      local others = table.map(room:getOtherPlayers(player), Util.IdMapper)
      if #others == 0 then return end
      local tos = room:askForChoosePlayers(player, others, 1, 1, "#hs__n_piaoyong_choose2discard", self.name,false)
      local t = room:getPlayerById(tos[1])
      local card = Fk:getCardById(room:askForCardChosen(player, t, "h", self.name, "#hs__n_piaoyong_discard"))
      room:throwCard(card, self.name, t, player)
    end
  end,
}
chengzhijie:addSkill(piaoyong)
Fk:loadTranslationTable{
  ["hs__n_chengzhijie"] = "程知节",
  ["#hs__n_chengzhijie"] = "混世魔王",
  ["designer:hs__n_chengzhijie"] = "修功",
  ["illustrator:hs__n_chengzhijie"] = "",

  ["hs__n_piaoyong"] = "朴勇",
  [":hs__n_piaoyong"] = "锁定技，当你于回合内使用：首张牌时，你观看一名其他角色所有手牌；第三张牌时，你弃置一名其他角色的一张手牌。",

  ["~hs__n_chengzhijie"] = "",
}

local qinqiong = General(extension, "hs__n_qinqiong", "tangz", 4)
local liegong = fk.CreateTriggerSkill{
  name = "hs__n_liegongx",
  events = {fk.Damaged, fk.CardUsing},
  can_trigger = function (self, event, target, player, data)
    if player:hasSkill(self) and target == player then
      return event == fk.Damaged or (event == fk.CardUsing and data.card.skillName == self.name)
    end
  end,
  on_cost = function (self, event, target, player, data)
    if event == fk.Damaged then
      local card = player.room:askForCard(player, 1, 1, false, self.name, true, ".", "#hs__n_liegongx_choose2Show")
      if not card then return end
      self.cost_data = {card = card}
      return true
    else
      return player.room:askForSkillInvoke(player, self.name, nil, "#hs__n_liegongx_invoke")
    end
  end,
  on_use = function (self, event, target, player, data)
    if event == fk.CardUsing then
      data.extraUse = true
      player:addCardUseHistory(data.card.trueName, -1)
    else
      H.ShowCards(player, self.cost_data.card)
    end
  end
}
local liegong_filter = fk.CreateFilterSkill{
  name = "#hs__n_liegongx_filter",
  card_filter = function(self, to_select, player)
    return player:hasSkill(self) and to_select:getMark(MarkEnum.ShownCards) > 0 and
    table.contains(player.player_cards[Player.Hand], to_select.id)
  end,
  view_as = function(self, to_select)
    local card = Fk:cloneCard("slash",to_select.suit, to_select.number)
    card.skillName = "hs__n_liegongx"
    return card
  end,
}
local liegong_targetmod = fk.CreateTargetModSkill{
  name = "#hs__n_liegongx_targetmod",
  bypass_times = function (self, player, skill, scope, card, to)
    return card and player:hasSkill(self) and skill.trueName == "slash_skill" and table.contains(card.skillNames, "hs__n_liegongx")
  end
}
liegong:addRelatedSkill(liegong_filter)
liegong:addRelatedSkill(liegong_targetmod)
qinqiong:addSkill(liegong)
Fk:loadTranslationTable{
  ["hs__n_qinqiong"] = "秦琼",
  ["#hs__n_qinqiong"] = "荡来军涛",
  ["designer:hs__n_qinqiong"] = "教父",
  ["illustrator:hs__n_qinqiong"] = "",

  ["hs__n_liegongx"] = "烈攻",
  [":hs__n_liegongx"] = "当你受到伤害后，你可以明置一张手牌；你的明置牌均视为无次数限制的【杀】。",
  ["#hs__n_liegongx_filter"] = "烈攻",
  ["#hs__n_liegongx_invoke"] = "烈攻：你可以明置一张手牌",

  ["~hs__n_qinqiong"] = "",
}

local weichigong = General(extension, "hs__n_weichigong", "tangz", 4)
local duozhen = fk.CreateTriggerSkill{
  name = "hs__n_duozhen",
  events = {fk.TargetSpecified, fk.AfterAskForCardUse, fk.AfterAskForCardResponse, fk.AfterAskForNullification},
  can_trigger = function (self, event, target, player, data)
    local room = player.room
    if not player:hasSkill(self) then return false end
    if target == player and event == fk.TargetSpecified then
      return #AimGroup:getAllTargets(data.tos) == 1 and data.to ~= player.id and data.card.color == Card.Black and table.find(room:getPlayerById(data.to):getCardIds("h"), function (cid) return Fk:getCardById(cid):getMark(MarkEnum.ShownCards) == 0 end) 
    else 
      if not data.eventData or data.eventData.from == player.id or not table.find(room:getPlayerById(data.eventData.from):getCardIds("h"), function (cid) return Fk:getCardById(cid):getMark(MarkEnum.ShownCards) > 0 end)
      then return false end
      if event == fk.AfterAskForCardResponse then
        return target == player and data.result
      end
      return (data.result and data.result.from == player.id) and (event == fk.AfterAskForNullification or target == player)
    end
 end,
 on_cost = function (self, event, target, player, data)
  local room = player.room
  if event == fk.TargetSpecified then
    if not room:askForSkillInvoke(player, self.name, nil, "#hs__n_douzhen_show::"..data.to) then return end
    local disabled_ids = table.filter(room:getPlayerById(data.to):getCardIds("h"), function (cid)
      return Fk:getCardById(cid):getMark(MarkEnum.ShownCards) > 0
    end)
    local showCards = U.askforCardsChosenFromAreas(player, room:getPlayerById(data.to), "h", self.name, "#hs__n_douzhen_show::"..data.to, disabled_ids)
    if showCards then 
      self.cost_data = {card = showCards}
      return true
    end
  else
    local t = room:getPlayerById(data.eventData.from)
    local disabled_ids = table.filter(t:getCardIds("h"), function (cid)
      return Fk:getCardById(cid):getMark(MarkEnum.ShownCards) == 0
    end)
    if not room:askForSkillInvoke(player, self.name, nil, "#hs__n_douzhen_aquire::"..t.id) then return end
    local card = U.askforCardsChosenFromAreas(player, t, "h", self.name, "#hs__n_douzhen_aquire::"..t.id, disabled_ids)
    if #card > 0 then
      self.cost_data = {card = card}
      return true
    end
  end
 end,
 on_use = function (self, event, target, player, data)
  local room = player.room
  if event == fk.TargetSpecified then
    H.ShowCards(room:getPlayerById(data.to), self.cost_data.card)
  else
    player.room:moveCardTo(self.cost_data.card, Player.Hand, player, fk.ReasonPrey, self.name, nil, true)
  end
 end
}
weichigong:addSkill(duozhen)
Fk:loadTranslationTable{
  ["hs__n_weichigong"] = "尉迟恭",
  ["#hs__n_weichigong"] = "百炼龙泉",
  ["designer:hs__n_weichigong"] = "小作坊",
  ["illustrator:hs__n_weichigong"] = "",

  ["hs__n_duozhen"] = "夺阵",
  [":hs__n_duozhen"] = "当你使用黑色牌指定其他角色为唯一目标后，你可以明置其一张手牌；当你响应其他角色使用的牌后，你可以获得其一张明置牌",
  ["#hs__n_douzhen_show"] = "夺阵：你可以明置 %dest 一张手牌",
  ["#hs__n_douzhen_aquire"] = "夺阵：你可以获得 %dest 一张明置牌",

  ["~hs__n_weichigong"] = "",
}

local liyuan = General(extension, "hs__n_liyuan", "tangz", 4)
liyuan.hidden = true
local hengque = fk.CreateTriggerSkill{
  name = "hs__n_hengque",
  events = {fk.CardUseFinished},
  -- can_trigger = function (self, event, target, player, data)
  --   return player:hasSkill(self) and player == target
  -- end,
  -- on_cost = function (self, event, target, player, data)
  --   local discard = player.room:askForDiscard(player, 1, 1, true, self.name, true, ".", "#hs__n_hengque_prompt", true)
  --   if discard and #discard > 0 then
  --     self.cost_data = {discard = discard}
  --     return true
  --   end
  -- end,
  -- on_use = function (self, event, target, player, data)
  --   local room = player.room
  --   room:throwCard(self.cost_data.discard, self.name, player, player)
  --   if player.dead then return end
  --   player:showCards(player:getCardIds("h"))
  --   if player.dead then return end
  --   local red = #table.filter(player:getCardIds("h"),function (cid) return Fk:getCardById(cid).color == Card.Red end)
  --   local black = #table.filter(player:getCardIds("h"),function (cid) return Fk:getCardById(cid).color == Card.Black end)
  --   if red == black then
  --     player:drawCards(1,self.name)
  --   end
  -- end
}
liyuan:addSkill(hengque)
Fk:loadTranslationTable{
  ["hs__n_liyuan"] = "李渊",
  ["#hs__n_liyuan"] = "囚牛嗅鼎",
  ["designer:hs__n_liyuan"] = "静谦",
  ["illustrator:hs__n_liyuan"] = "",

  ["hs__n_hengque"] = "衡阙",
  [":hs__n_hengque"] = "出牌阶段，你可以令一名角色摸一张牌，然后弃置一名与其势力相同的角色一张牌，若为同一角色或手牌数不相等，此技能本回合失效。",
  -- ["#hs__n_hengque_prompt"] = "衡阙：你可以弃置一张牌并展示所有手牌，若红色牌与黑色牌数量相等则摸一张牌",

  ["~hs__n_liyuan"] = "",
}

local lilongji = General(extension, "hs__n_lilongji", "tangz", 4)
local fenxiu = fk.CreateTriggerSkill{
  name = "hs__n_fenxiu",
  events = {fk.EventPhaseStart},
  can_trigger = function (self, event, target, player, data)
    return player:hasSkill(self) and H.compareKingdomWith(player, target) and target.phase == Player.Finish
     and not player:isKongcheng() and #H.GetShownCards(player) == 0
  end,
  on_cost = function (self, event, target, player, data)
    local room = player.room
    local to = room:askForChoosePlayers(player, table.map(room.alive_players, Util.IdMapper), 1, 1, "#hs__n_lilongji_prompt", self.name, true)
    if #to > 0 then
      self.cost_data = {to = to[1]}
      return true
    end
  end,
  on_use = function (self, event, target, player, data)
    H.ShowCards(player,player:getCardIds("h"))
    if player.dead then return end
    player.room:damage{
      from = player,
      to = player.room:getPlayerById(self.cost_data.to),
      damageType = fk.FireDamage,
      damage = 1,
      skillName = self.name
    }
  end
}
lilongji:addSkill(fenxiu)
Fk:loadTranslationTable{
  ["hs__n_lilongji"] = "李隆基",
  ["#hs__n_lilongji"] = "昏霁销天光",
  ["designer:hs__n_lilongji"] = "祭祀",
  ["illustrator:hs__n_lilongji"] = "",
  
  ["hs__n_fenxiu"] = "焚绣",
  [":hs__n_fenxiu"] = "与你势力相同角色的结束阶段，若你没有明置的手牌，你可以明置所有手牌，然后对一名角色造成1点火焰伤害",
  ["#hs__n_lilongji_prompt"] = "焚绣：你可以选择一名角色，对其造成1点火焰伤害",

  ["~hs__n_lilongji"] = ""
}

local fangxuanling = General(extension, "hs__n_fangxuanling", "tangz", 3)
local xianjue = fk.CreateViewAsSkill{
  name = "hs__n_xianjue",
  pattern = ".",
  interaction = function(self)
    local all_names = U.getAllCardNames("bt")
    local able_names = {}
    for _, value in ipairs(Self:getCardIds("h")) do
      local c = Fk:getCardById(value)
      if c:getMark(MarkEnum.ShownCards) > 0 and table.contains(all_names, c.name) and (not Fk.currentResponsePattern or Exppattern:Parse(Fk.currentResponsePattern):match(c)) then
        table.insertIfNeed(able_names, c.name)
      end
    end
    able_names = U.getViewAsCardNames(Self,self.name,able_names,table.filter(Self:getCardIds(Player.Hand), function (cid) return Fk:getCardById(cid):getMark(MarkEnum.ShownCards) == 0 end))
    return U.CardNameBox {
      choices = able_names,
      all_choices = all_names,
      default_choice = "AskForCardsChosen"
    }
  end,
  view_as = function (self, cards, player)
    if Fk.all_card_types[self.interaction.data] == nil then return end
    local card = Fk:cloneCard(self.interaction.data)
    card:addSubcards(table.filter(Self:getCardIds(Player.Hand), function (cid) return Fk:getCardById(cid):getMark(MarkEnum.ShownCards) == 0 end))
    card.skillName = self.name
    return card
  end,
  enabled_at_play = function(self, player)
    local all_names = U.getAllCardNames("bt")
    local able_names = {}
    for _, value in ipairs(Self:getCardIds("h")) do
      local c = Fk:getCardById(value)
      if c:getMark(MarkEnum.ShownCards)>0 and table.contains(all_names,c.name) and (not Fk.currentResponsePattern or Exppattern:Parse(Fk.currentResponsePattern):match(c)) then
        table.insertIfNeed(able_names,c.name)
      end
    end
    able_names = U.getViewAsCardNames(Self,self.name,able_names,table.filter(Self:getCardIds(Player.Hand), function (cid) return Fk:getCardById(cid):getMark(MarkEnum.ShownCards) == 0 end))
    return player:usedSkillTimes(self.name, Player.HistoryTurn) == 0 and #able_names > 0 and 
      table.find(Self:getCardIds(Player.Hand), function (element, index, array)
      return Fk:getCardById(element):getMark(MarkEnum.ShownCards) == 0
    end)
  end,
  enabled_at_response = function (self, player, response)
    return not response and player:usedSkillTimes(self.name, Player.HistoryTurn) == 0 
     and table.find(Self:getCardIds(Player.Hand), function (cid) return Fk:getCardById(cid):getMark(MarkEnum.ShownCards) > 0 and Exppattern:Parse(Fk.currentResponsePattern):match(Fk:getCardById(cid)) end) 
     and table.find(Self:getCardIds(Player.Hand), function (cid) return Fk:getCardById(cid):getMark(MarkEnum.ShownCards) == 0 end)
  end
}
local yiqin = fk.CreateActiveSkill{
  name = "hs__n_yiqin",
  can_use = function (self, player, card, extra_data)
    local suits = {}
    for _, p in ipairs(Fk:currentRoom().alive_players) do
      for _, c in ipairs(p:getCardIds("h")) do
        if Fk:getCardById(c):getMark(MarkEnum.ShownCards) > 0 then
          table.insertIfNeed(suits,Fk:getCardById(c).suit)
        end
      end
    end
    table.removeOne(suits, Card.NoSuit)
    return player:usedSkillTimes(self.name, Player.HistoryPhase) == 0 and #suits > 0
  end,
  card_filter = Util.FalseFunc,
  target_filter = Util.FalseFunc,
  on_use = function (self, room, use)
    local player = room:getPlayerById(use.from)
    local suits = {}
    for _, p in ipairs(Fk:currentRoom().alive_players) do
      for _, c in ipairs(p:getCardIds("h")) do
        if Fk:getCardById(c):getMark(MarkEnum.ShownCards) > 0 then
          table.insertIfNeed(suits, Fk:getCardById(c).suit)
        end
      end
    end
    table.removeOne(suits, Card.NoSuit)
    local cards = room:getNCards(#suits)
    room:moveCards({
      ids = cards,
      toArea = Card.Processing,
      moveReason = fk.ReasonPut,
      proposer = use.from,
    })
    local targets = room:askForChoosePlayers(player, table.map(room:getAllPlayers(), Util.IdMapper), 1, #suits, "#hs__n_yiqin_target")
    use.extra_data = use.extra_data or {}
    use.extra_data.AGFilled = cards
    use.extra_data.AGResult = {}
    table.forEach(room.players, function(p) room:fillAG(p, cards) end)
    for _, to_id in ipairs(targets) do
      local to = room:getPlayerById(to_id)
      if to.dead then goto continue end
      local chosen = room:askForAG(to, use.extra_data.AGFilled, false, self.name)
      room:takeAG(to, chosen, room.players)
      table.insert(use.extra_data.AGResult, {to_id, chosen})
      room:moveCardTo(chosen, Card.PlayerHand, to, fk.ReasonPrey, self.name, nil, true, to_id)
      if to.dead then return end
      H.ShowCards(to,chosen)
      table.removeOne(use.extra_data.AGFilled, chosen)
      ::continue::
    end 
    if use.extra_data and use.extra_data.AGFilled then
      table.forEach(room.players, function(p) room:closeAG(p) end)
      local toDiscard = table.filter(use.extra_data.AGFilled, function(id) return room:getCardArea(id) == Card.Processing end)
      if #toDiscard > 0 then
        room:moveCards({
          ids = toDiscard,
          toArea = Card.DiscardPile,
          moveReason = fk.ReasonPutIntoDiscardPile,
        })
      end
    end
    use.extra_data.AGFilled = nil
  end
}
fangxuanling:addSkill(xianjue)
fangxuanling:addSkill(yiqin)
Fk:loadTranslationTable{
  ["hs__n_fangxuanling"] = "房玄龄",
  ["#hs__n_fangxuanling"] = "西园上才",
  ["designer:hs__n_fangxuanling"] = "修功&教父",
  ["illustrator:hs__n_fangxuanling"] = "",

  ["hs__n_xianjue"] = "先决",
  [":hs__n_xianjue"] = "每回合限一次，你可以将所有暗置牌当一张明置牌中的任意基本牌或非延时锦囊牌使用。",
  ["hs__n_yiqin"] = "益亲",
  [":hs__n_yiqin"] = "出牌阶段限一次，你可以展示牌堆顶 X 张牌并选择至多等量名角色（X 为所有明置牌总花色数），然后这些角色依次获得其中一张牌并明置之",
  ["#hs__n_yiqin_target"] = "益亲：你可令至多等量角色依次获得其中一张牌并明置之",

  ["~hs__n_fangxuanling"] = "",
}

local duruhui = General(extension, "hs__n_duruhui", "tangz", 3)
local junda = fk.CreateTriggerSkill{
  name = "hs__n_junda",
  events = {fk.EventPhaseStart},
  anim_type = "drawcard",
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and player.phase == Player.Draw and
      table.find(player.room:getOtherPlayers(player, false), function(p) return not p:isKongcheng() end)
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local cards = {}
    local suits = {}
    local i = 1
    while i < #room.draw_pile do
      if #cards == 0 then
        table.insert(cards, room.draw_pile[i])
        table.insert(suits, Fk:getCardById(room.draw_pile[i]).suit)
        room:showCards(room.draw_pile[i])
        room:delay(800)
      else
        table.insert(cards, room.draw_pile[i])
        room:showCards(room.draw_pile[i])
        room:delay(800)
        if table.contains(suits, Fk:getCardById(room.draw_pile[i]).suit) then
          break
        end
        table.insert(suits, Fk:getCardById(room.draw_pile[i]).suit)
      end
      i = i + 1
    end
    local to_get = room:askForPoxi(player, "hs__n_junda_chooseToGet", {{self.name, cards}}, nil, false)
    room:obtainCard(player, to_get, true, fk.ReasonJustMove, player.id, self.name)
    H.ShowCards(player, to_get)
    return true
  end,
}
Fk:addPoxiMethod{
  name = "hs__n_junda_chooseToGet",
  card_filter = function (to_select, selected, data, extra_data)
    if not selected or #selected == 0 then return true end
    local types = {}
    table.forEach(selected, function (cid) table.insertIfNeed(types, Fk:getCardById(cid).type) end)
    return not table.contains(types, Fk:getCardById(to_select).type)
  end,
  feasible = function (selected, data, extra_data)
    return #selected > 0
  end,
  prompt = "#hs__n_junda_choose"
}
local houduan = fk.CreateTriggerSkill{
  name = "hs__n_houduan",
  events = {fk.CardUseFinished},
  can_trigger = function (self, event, target, player, data)
    return player:hasSkill(self) and H.compareKingdomWith(player,target) and data.card.is_damage_card
  end,
  on_cost = function (self, event, target, player, data)
    local room = player.room
    local able_choose = {}
    for _, p in pairs(data.tos[1]) do 
      if #room.logic:getActualDamageEvents(1, function (e) return e.data[1].to.id == p and e.data[1].card and e.data[1].card == data.card end) > 0 then
        table.insert(able_choose, p)
      end
    end
    if #able_choose == 0 then return end
    local ids = table.concat(table.filter(player:getCardIds("h"), function (cid) return Fk:getCardById(cid):getMark(MarkEnum.ShownCards) > 0 and data.card.suit == Fk:getCardById(cid).suit end), ",")
    if #ids == 0 then return end
    local p, card = room:askForChooseCardAndPlayers(player, able_choose, 1, 1, ".|.|.|.|.|.|"..ids, "#hs__n_houduan_prompt", self.name, true, true)
    if card then
      self.cost_data = {card = card, to = p[1]}
      return true 
    end
  end,
  on_use = function (self, event, target, player, data)
    local room = player.room
    room:throwCard(self.cost_data.card, self.name, player, player)
    room:damage{
      from = player,
      to = room:getPlayerById(self.cost_data.to),
      damage = 1,
      skillName = self.name
    }
  end
}
duruhui:addSkill(junda)
duruhui:addSkill(houduan)
Fk:loadTranslationTable{
  ["hs__n_duruhui"] = "杜如晦",
  ["#hs__n_duruhui"] = "",
  ["designer:hs__n_duruhui"] = "",
  ["illustrator:hs__n_duruhui"] = "",

  ["hs__n_junda"] = "俊达",
  [":hs__n_junda"] = "摸牌阶段，你可以改为依次展示牌堆顶的牌直至出现相同花色的牌，然后你获得其中任意张类别各不相同的牌并明置之",
  ["hs__n_houduan"] = "后断",
  [":hs__n_houduan"] = "与你势力相同角色于其回合内使用伤害类牌结算后，你可以弃置一张花色相同的明置牌，对此牌造成过伤害的一名角色造成1点伤害",
  ["hs__n_junda_chooseToGet"] = "俊达",
  ["#hs__n_junda_choose"] = "俊达：请选择类别各不相同的牌",
  ["#hs__n_junda_show"] = "展示",
  ["#hs__n_houduan_prompt"] = "后断：你可以弃置一张花色相同的明置牌，对此牌造成过伤害的一名角色造成1点伤害",

  ["~hs__n_duruhui"] = "",
}

local sunsimiao = General(extension, "hs__n_sunsimiao", "tangz", 4)
sunsimiao.hidden = true
local youyi = fk.CreateTriggerSkill{
  name = "hs__n_youyi",
  anim_type = "special",
  events = {fk.TargetConfirmed, fk.EventPhaseStart},
  can_trigger = function (self, event, target, player, data)
    if event == fk.TargetConfirmed then
      return player:hasSkill(self) and H.compareKingdomWith(player, target) and data.card.color == Card.Black
    else
      return player:hasSkill(self) and player.phase == Player.Play and player == target
    end
  end,
  on_cost = function (self, event, target, player, data)
    if event == fk.TargetConfirmed then
      local notshowns = table.filter(player:getCardIds("h"), function (id) return Fk:getCardById(id):getMark(MarkEnum.ShownCards) == 0 and Fk:getCardById(id).color == Card.Black end)
      local pat = ".|.|.|.|.|.|"..table.concat(notshowns, ",")
      local cards = player.room:askForCard(player, 1, 1, false, self.name, true, pat, "#hs__n_youyi-show")
      if #cards > 0 then
        self.cost_data = {idx = 1, cards = cards}
        return true
      end
    else
      local showns = H.GetShownCards(player)
      local pat = ".|.|.|.|.|.|"..table.concat(showns, ",")
      local cards = player.room:askForCard(player, 1, 998, false, self.name, true, pat, "#hs__n_xiandeng-dis")
      if #cards > 0 then
        self.cost_data = {idx = 2, cards = cards}
        return true
      end
    end
  end,
  on_use = function (self, event, target, player, data)
    if self.cost_data.idx == 1 then
      H.ShowCards(player, self.cost_data.cards)
    else
      player.room:throwCard(self.cost_data.cards, self.name, player)
      player:drawCards(#self.cost_data.cards, self.name)
    end
  end,
}
local chuanfang = fk.CreateTriggerSkill{
  name = "hs__n_chuanfang",
}
sunsimiao:addSkill(youyi)
sunsimiao:addSkill(chuanfang)
Fk:loadTranslationTable{
  ["hs__n_sunsimiao"] = "孙思邈",
  ["#hs__n_sunsimiao"] = "",
  ["designer:hs__n_sunsimiao"] = "",
  ["illustrator:hs__n_sunsimiao"] = "",
  
  ["hs__n_youyi"] = "游医",
  [":hs__n_youyi"] = "与你势力相同角色成为黑色牌的目标后，你可明置一张黑色牌；出牌阶段开始时，你可弃置任意张明置牌，摸等量的牌。",
  ["hs__n_chuanfang"] = "传方",
  [":hs__n_chuanfang"] = "",

  ["~hs__n_sunsimiao"] = "",
}

local xuerengui = General(extension, "hs__n_xuerengui", "tangz", 4)
xuerengui.hidden = true
local weishi = fk.CreateTriggerSkill{
  name = "hs__n_weishi",
}
xuerengui:addSkill(weishi)
Fk:loadTranslationTable{
  ["hs__n_xuerengui"] = "薛仁贵",
  ["#hs__n_xuerengui"] = "",
  ["designer:hs__n_xuerengui"] = "",
  ["illustrator:hs__n_xuerengui"] = "",
  
  ["hs__n_weishi"] = "危示",
  [":hs__n_weishi"] = "",

  ["~hs__n_xuerengui"] = "",
}

local xiaoyu = General(extension, "hs__n_xiaoyu", "tangz", 4)
xiaoyu.hidden = true
local wujian = fk.CreateTriggerSkill{
  name = "hs__n_wujian",
}
local gengzhong = fk.CreateTriggerSkill{
  name = "hs__n_gengzhong",
}
xiaoyu:addSkill(wujian)
xiaoyu:addSkill(gengzhong)
Fk:loadTranslationTable{
  ["hs__n_xiaoyu"] = "萧瑀",
  ["#hs__n_xiaoyu"] = "",
  ["designer:hs__n_xiaoyu"] = "老猫",
  ["illustrator:hs__n_xiaoyu"] = "",
  
  ["hs__n_wujian"] = "忤谏",
  [":hs__n_wujian"] = "若你手牌数为全场最多，你可以将手牌调整至全场最少，视为使用【无懈可击】。",
  ["hs__n_gengzhong"] = "耿忠",
  [":hs__n_gengzhong"] = "你于失去过明置牌的回合内使用锦囊牌不能被响应；你于失去过基本牌的回合内使用暗置牌无次数限制。",

  ["~hs__n_xiaoyu"] = "",
}

local guoziyi = General(extension, "hs__n_guoziyi", "tangz", 4)
local fubian = fk.CreateTriggerSkill{
  name = "hs__n_fubian",
  events = {fk.TargetSpecified},
  can_trigger = function (self, event, target, player, data)
    return player:hasSkill(self) and H.compareKingdomWith(player, target, true) and not player:isNude() and data.firstTarget
      and table.find(AimGroup:getAllTargets(data.tos), function (p)
        return H.compareKingdomWith(player, player.room:getPlayerById(p))
      end)
  end,
  on_cost = function (self, event, target, player, data)
    local cards = player.room:askForCard(player,1 ,1, true, self.name, true, ".", "#hs__n_fubian-invoke::"..target.id)
    if #cards > 0  then
      self.cost_data = {tos = {target.id}, cards = cards}
      return true
    end
  end,
  on_use = function (self, event, target, player, data)
    local room = player.room
    room:obtainCard(target, self.cost_data.cards, false, fk.ReasonGive, player.id, self.name)
    if player:isKongcheng() or target:isKongcheng() then return end
    local jointtable = U.askForJointCard({player,target}, 1, 1, false, self.name, false, ".", "#hs__n_fubian-show")
    local nuil, type = false, nil
    for p, c in pairs(jointtable) do
      room:getPlayerById(p):showCards(c)
      if type == nil then
        type = Fk:getCardById(c[1]).type
      else
        if type == Fk:getCardById(c[1]).type then
          nuil = true
        end
      end
    end
    if nuil then
      local targets = table.filter(room.alive_players, function (p)
        return H.compareKingdomWith(player, p)
      end)
      data.nullifiedTargets = data.nullifiedTargets or {}
      for _, p in ipairs(targets) do
        table.insertIfNeed(data.nullifiedTargets, p.id)
      end
    end
  end,
}
guoziyi:addSkill(fubian)
Fk:loadTranslationTable{
  ["hs__n_guoziyi"] = "郭子仪",
  ["#hs__n_guoziyi"] = "神臣圣砥",
  ["designer:hs__n_guoziyi"] = "小曹神",
  ["illustrator:hs__n_guoziyi"] = "",
  
  ["hs__n_fubian"] = "抚边",
  [":hs__n_fubian"] = "与你势力不同的角色使用牌指定与你势力相同的角色为目标后，你可以交给其一张牌并与其同时展示一张手牌，若两牌类型相同，此牌对所有与你势力相同的角色无效。",
  ["#hs__n_fubian-invoke"] = "抚边：你可交给 %dest 一张牌",
  ["#hs__n_fubian-show"] = "抚边：请展示一张牌",

  ["~hs__n_guoziyi"] = "",
}

local zhangsun = General(extension, "hs__n_zhangsun", "tangz", 3, 3, General.Female)
local qiwo = fk.CreateTriggerSkill{
  name = "hs__n_qiwo",
  anim_type = "support",
  events = {fk.EventPhaseStart},
  can_trigger = function (self, event, target, player, data)
    if player:hasSkill(self) and target.phase == Player.Play and H.compareKingdomWith(player, target) then
      return table.find(player:getCardIds("h"), function (id)
        return Fk:getCardById(id):getMark(MarkEnum.ShownCards) == 0 end)
    end
  end,
  on_cost = function (self, event, target, player, data)
    local notshowns = table.filter(player:getCardIds("h"), function (id)
      return Fk:getCardById(id):getMark(MarkEnum.ShownCards) == 0 end)
    local pat = ".|.|.|.|.|.|"..table.concat(notshowns, ",")
    local cards = player.room:askForCard(player, 1, 1, false, self.name, true, pat, "#hs__n_qiwo-show")
    if #cards > 0 then
      self.cost_data = {tos = {target.id}, cards = cards}
      return true
    end
  end,
  on_use = function (self, event, target, player, data)
    H.ShowCards(player, self.cost_data.cards)
  end,
}
local qiwo_delay = fk.CreateTriggerSkill{
  name = "#hs__n_qiwo_delay",
  anim_type = "support",
  events = {fk.CardUsing},
  can_trigger = function (self, event, target, player, data)
    if target.phase == Player.Play and player:usedSkillTimes(qiwo.name) > 0 then
      local logic = player.room.logic
      local use_event = logic:getCurrentEvent()
      local mark_name = "hs__n_qiwo-record"
      local mark = player:getMark(mark_name)
      if mark == 0 then
        logic:getEventsOfScope(GameEvent.UseCard, 1, function (e)
          local last_use = e.data[1]
          if last_use.from == target.id then
            mark = e.id
            player.room:setPlayerMark(player, mark_name, mark)
            return true
          end
          return false
        end, Player.HistoryPhase)
      end
      return mark == use_event.id and table.find(H.GetShownCards(player), function (cid)
        return Fk:getCardById(cid):compareSuitWith(data.card)
      end)
    end
  end,
  on_cost = function (self, event, target, player, data)
    local filters = table.filter(H.GetShownCards(player), function (cid)
      return Fk:getCardById(cid):compareSuitWith(data.card)
    end)
    local pat = ".|.|.|.|.|.|"..table.concat(filters, ",")
    local cards = player.room:askForCard(player, #filters, #filters, false, self.name, true, pat, "#hs__n_qiwo-dis")
    if #cards > 0 then
      self.cost_data = {tos = {target.id}, cards = cards}
      return true
    end
  end,
  on_use = function (self, event, target, player, data)
    local room = player.room
    room:throwCard(self.cost_data.cards, qiwo.name, player)
    data.additionalEffect = 1
  end,
}
local clear_mark = function (player,data)
  for _, move in ipairs(data) do
    if move.from == player.id then
      for _, info in ipairs(move.moveInfo) do
        if info.fromArea == Card.PlayerHand then
          local c = Fk:getCardById(info.cardId)
          if c:getMark("hs__n_qide_showMark") > 0 then
            player.room:setCardMark(c,"hs__n_qide_showMark",0)
          end
        end
      end
    end
  end
end
local qide = fk.CreateTriggerSkill{
  name = "hs__n_qide",
  events = {fk.AfterCardsMove, "fk.AfterCardsShown", "fk.AfterCardsHidden"},
  can_trigger = function (self, event, target, player, data)
    if not player:hasSkill(self) or player:usedSkillTimes(self.name) >= 1 then return end
    if event == fk.AfterCardsMove then
      local showCards = player:getTableMark("hs__n_qide_showMark")
      if not showCards or #showCards == 0 then return false end
      for _, move in ipairs(data) do
        if move.from == player.id then
          for _, info in ipairs(move.moveInfo) do
            if info.fromArea == Card.PlayerHand then
              clear_mark(player, data)
              return table.contains(showCards, info.cardId)
            end
          end
        end
      end
    else
      return true
    end
  end,
  on_cost = function (self, event, target, player, data)
    local cards_num = #H.GetShownCards(player)
    local target = player.room:askForChoosePlayers(player,table.map(table.filter(player.room.alive_players, function (p) return #H.GetShownCards(p) == cards_num and p ~= player end), Util.IdMapper), 1, 1, "hs__n_qide_prompt", self.name, true)
    if #target > 0 then
      self.cost_data = {to = target[1]}
      return true
    end
  end,
  on_use = function (self, event, target, player, data)
    local room = player.room
    local to = room:getPlayerById(self.cost_data.to)
    to:drawCards(1, self.name)
    if to.dead then return end
    local showCards = H.GetShownCards(player)
    if #showCards == 0 then return end
    local pattern = ".|.|.|.|.|.|"..table.concat(showCards, ",")
    if #room:askForDiscard(to, 1, 1, false, self.name, true, pattern, "hs__n_qide_discardPrompt::"..player.id) > 0 then
      player:drawCards(1,self.name)
    end
  end,

  refresh_events = {fk.BeforeCardsMove},
  can_refresh = function (self, event, target, player, data)
    if not player:hasSkill(self) then return false end
    for _, move in ipairs(data) do
      if move.from == player.id then
        return true
      end
    end
  end,
  on_refresh = function (self, event, target, player, data)
    local room = player.room
    for _, cid in ipairs(player:getCardIds("h")) do
      if Fk:getCardById(cid):getMark(MarkEnum.ShownCards) > 0 then
        player.room:addTableMark(player, "hs__n_qide_showMark", cid)
      end
    end
    room.logic:getCurrentEvent():addCleaner(function () room:setPlayerMark(player, "hs__n_qide_showMark", 0) end)
  end
}
qiwo:addRelatedSkill(qiwo_delay)
zhangsun:addSkill(qiwo)
zhangsun:addSkill(qide)
Fk:loadTranslationTable{
  ["hs__n_zhangsun"] = "长孙皇后",
  ["#hs__n_zhangsun"] = "北辰鸾佑",
  ["designer:hs__n_zhangsun"] = "修功",
  ["illustrator:hs__n_zhangsun"] = "",
  
  ["hs__n_qiwo"] = "启沃",
  [":hs__n_qiwo"] = "与你势力相同的角色出牌阶段开始时，你可以明置一张手牌，若如此做，当其于此阶段使用首张牌时，你可以弃置所有花色相同的明置牌，令此牌结算两次。",
  ["hs__n_qide"] = "齐德",
  [":hs__n_qide"] = "每回合限一次，当你的明置牌数变化后，你可以令一名明置牌数等于你的其他角色摸一张牌，然后其可以弃置一张明置牌，令你摸一张牌。",
  ["#hs__n_qiwo_delay"] = "启沃",
  ["#hs__n_qiwo-show"] = "启沃：你可明置一张手牌",
  ["#hs__n_qiwo-dis"] = "启沃：你可弃置所有同花色的明置牌，令此牌结算两次",
  ["hs__n_qide_prompt"] = "齐德：你可以选择一名明置牌数与你相等的其他角色，令其摸一张牌",
  ["hs__n_qide_discardPrompt"] = "齐德：你可以弃置一张明置牌，令 %dest 摸一张牌",

  ["~hs__n_zhangsun"] = "",
}

local yangyuhuan = General(extension, "hs__n_yangyuhuan", "tangz", 3, 3, General.Female)
local danchong = fk.CreateTriggerSkill{
  name = "hs__n_danchong",
  anim_type = "drawcard",
  events = {fk.AfterCardsMove},
  can_trigger = function (self, event, target, player, data)
    if player:hasSkill(self) then
      local cards = {}
      for _, move in ipairs(data) do
        if move.to == player.id and move.toArea == Card.PlayerHand then
          for _, info in ipairs(move.moveInfo) do
            local c = Fk:getCardById(info.cardId)
            if c.suit == Card.Heart then
              table.insert(cards, c.id)
            end
          end
        end
      end
      if #cards == 0 then return end
      cards = U.moveCardsHoldingAreaCheck(player.room, cards)
      cards = table.filter(cards, function (id)
        return Fk:getCardById(id):getMark(MarkEnum.ShownCards) == 0 end)
      if #cards > 0 then
        self.cost_data = cards
        return true
      end
    end
  end,
  on_use = function (self, event, target, player, data)
    H.ShowCards(player, self.cost_data)
    player:drawCards(1, self.name)
  end,

  refresh_events = {fk.CardEffecting},
  can_refresh = function (self, event, target, player, data)
    return player:hasShownSkill(self) and player == target and data.card.suit == Card.Heart and data.from ~= player.id
  end,
  on_refresh = function (self, event, target, player, data)
    data.additionalDamage = (data.additionalDamage or 0) + 1
    data.additionalRecover = (data.additionalRecover or 0) + 1
  end,
}
local xiuhua = fk.CreateTriggerSkill{
  name = "hs__n_xiuhua",
  anim_type = "control",
  frequency = Skill.Compulsory,
  events = {fk.EventPhaseStart},
  can_trigger = function (self, event, target, player, data)
    if player:hasSkill(self) and player == target and player.phase == Player.Play then
      local tos = table.filter(player.room.alive_players, function (p)
        return p:getHandcardNum() < player:getHandcardNum()
      end)
      if #tos > 0 then
        self.cost_data = {tos = table.map(tos, Util.IdMapper)}
        return true
      end
    end
  end,
  on_use = function (self, event, target, player, data)
    local tos = self.cost_data.tos
    local room = player.room
    room:sortPlayersByAction(tos)
    for _, pid in ipairs(tos) do
      local p = room:getPlayerById(pid)
      if not p.dead then
        local choices = {}
        if table.find(p:getCardIds("h"), function (id) return not p:prohibitDiscard(Fk:getCardById(id)) end) then
          table.insert(choices, "hs__n_xiuhua-discard")
        end
        if H.getGeneralsRevealedNum(p) == 2 then
          local disable_choices = {}
          if not (p.general ~= "anjiang" and not p.general:startsWith("blank_") and not string.find(p.general, "lord")) then -- 耦合君主
            table.insert(disable_choices, p.general)
          end
          if not (p.deputyGeneral ~= "anjiang" and not p.deputyGeneral:startsWith("blank_")) then
            table.insert(disable_choices, p.deputyGeneral)
          end
          if #disable_choices ~= 2 then
            table.insert(choices, "hs__n_xiuhua-hide")
          end
        end
        if #choices > 0 then
          local choice = room:askForChoice(p, choices, self.name)
          if choice == "hs__n_xiuhua-discard" then
            room:askForDiscard(p, 1, 1, false, self.name, false)
          else
            local isDeputy = H.doHideGeneral(room, p, p ,self.name)
            room:setPlayerMark(p, "@hs__n_xiuhua_reveal-turn", H.getActualGeneral(p, isDeputy))
            local record = type(p:getMark(MarkEnum.RevealProhibited .. "-turn")) == "table" and p:getMark(MarkEnum.RevealProhibited .. "-turn") or {}
            table.insert(record, isDeputy and "d" or "m")
            room:setPlayerMark(p, MarkEnum.RevealProhibited .. "-turn", record)
          end
        end
      end
    end
  end,
}
yangyuhuan:addSkill(danchong)
yangyuhuan:addSkill(xiuhua)
Fk:loadTranslationTable{
  ["hs__n_yangyuhuan"] = "杨玉环",
  ["#hs__n_yangyuhuan"] = "润白惭芳",
  ["designer:hs__n_yangyuhuan"] = "教父 ",
  ["illustrator:hs__n_yangyuhuan"] = "",
  
  ["hs__n_danchong"] = "丹宠",
  [":hs__n_danchong"] = "当你获得红桃牌后，你可以明置之并摸一张牌；其他角色对你使用的红桃牌基数+1 。",
  ["hs__n_xiuhua"] = "羞花",
  [":hs__n_xiuhua"] = "锁定技，出牌阶段开始时，你令所有手牌数小于你的角色选择一项：1.弃置一张手牌；2.暗置一张武将牌且本回合不能明置之。",
  ["hs__n_xiuhua-discard"] = "弃置一张手牌",
  ["hs__n_xiuhua-hide"] = "暗置武将牌且本回合不能明置",
  ["@hs__n_xiuhua_reveal-turn"] = "羞花 禁亮",

  ["~hs__n_yangyuhuan"] = "",
}

local chaishao = General(extension, "hs__n_chaishao", "tangz", 4)
local xiandeng = fk.CreateTriggerSkill{
  name = "hs__n_xiandeng",
  events = {fk.Damage, fk.EventPhaseStart},
  can_trigger = function (self, event, target, player, data)
    if event == fk.Damage then
      return player:hasSkill(self) and player == target and table.find(player:getCardIds("h"), function (id)
        return Fk:getCardById(id):getMark(MarkEnum.ShownCards) == 0 end)
    else
      return player:hasSkill(self) and player == target and player.phase == Player.Start and #H.GetShownCards(player) >= player.hp
    end
  end,
  on_cost = function (self, event, target, player, data)
    if event == fk.Damage then
      local notshowns = table.filter(player:getCardIds("h"), function (id)
        return Fk:getCardById(id):getMark(MarkEnum.ShownCards) == 0 end)
      local pat = ".|.|.|.|.|.|"..table.concat(notshowns, ",")
      local cards = player.room:askForCard(player, 1, 1, false, self.name, true, pat, "#hs__n_xiandeng-show")
      if #cards > 0 then
        self.cost_data = cards
        return true
      end
    else
      local showns = H.GetShownCards(player)
      local pat = ".|.|.|.|.|.|"..table.concat(showns, ",")
      local cards = player.room:askForCard(player, player.hp, 998, false, self.name, true, pat, "#hs__n_xiandeng-dis")
      if #cards > 0 then
        self.cost_data = cards
        return true
      end
    end
  end,
  on_use = function (self, event, target, player, data)
    local room = player.room
    if event == fk.Damage then
      H.ShowCards(player, self.cost_data)
    else
      room:throwCard(self.cost_data, self.name, player)
      H.addHegMark(room, player, "vanguard")
    end
  end,
}
chaishao:addSkill(xiandeng)
Fk:loadTranslationTable{
  ["hs__n_chaishao"] = "柴绍",
  ["#hs__n_chaishao"] = "善始令终",
  ["designer:hs__n_chaishao"] = "静谦",
  ["illustrator:hs__n_chaishao"] = "",
  
  ["hs__n_xiandeng"] = "先登",
  [":hs__n_xiandeng"] = "当你造成伤害后，你可以明置一张手牌；准备阶段，你可以弃置至少你体力值数张明置牌，然后获得一个“先驱”标记。",
  ["#hs__n_xiandeng-show"] = "先登：你可以明置一张手牌",
  ["#hs__n_xiandeng-dis"] = "先登：你可以弃置至少你体力值数张明置牌，然后获得“先驱”",

  ["~hs__n_chaishao"] = "",
}

return extension
